package com.qdlc.p2p.biz.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.service.UserWineCouponsService;
import com.qdlc.p2p.common.constant.UserWineCouponsCategory;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.util.BeanCopierUtils;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.common.dao.jpa.BaseDaoImpl;
import com.qdlc.p2p.dal.common.model.jpa.PageDataList;
import com.qdlc.p2p.dal.dao.UserDao;
import com.qdlc.p2p.dal.dao.UserWineCouponsDao;
import com.qdlc.p2p.dal.dao.WineCouponsDao;
import com.qdlc.p2p.dal.dto.BorrowTender;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserWineCoupons;
import com.qdlc.p2p.dal.dto.WineCoupons;
import com.qdlc.p2p.dal.model.UserWineCouponsModel;
import com.qdlc.p2p.dal.model.WineCouponsModel;

/**
 * 用户酒券获取记录Service
 *
 * @author ygw
 * @version 1.1.0.0
 * @date 2016年5月6日 下午3:46:19
 */
@Service("userWineCouponsService")
public class UserWineCouponsServiceImpl extends BaseDaoImpl<UserWineCoupons> implements UserWineCouponsService {

    private static Logger logger = Logger.getLogger(UserWineCouponsServiceImpl.class);

    @Resource
    private UserWineCouponsDao userWineCouponsDao;

    @Resource
    private WineCouponsDao wineCouponsDao;

    @Resource
    private UserDao userDao;
    
    @PersistenceContext
	protected EntityManager em;

    private static String WEB_URL = SystemConfigHelper.getValue(Nid.WEB_URL);

    static {
        WEB_URL = WEB_URL.replace("http:", "").replace("https:", "");
    }

    @Override
    public UserWineCoupons save(UserWineCoupons userWineCoupons) {
        return userWineCouponsDao.save(userWineCoupons);
    }

    @Override
    public PageDataList<UserWineCouponsModel> list(UserWineCouponsModel model) {
        return userWineCouponsDao.list(model);
    }

    @SuppressWarnings("static-access")
    @Override
    public UserWineCoupons giveWineCoupons(long toUserId, long wineCouponsId, String sourceType) {
        //获取用户
        User user = userDao.find(toUserId);
        if (null == user) {
            logger.info("用户不存在，用户id:" + toUserId);
            return null;
        }
        //获取酒券方案
        WineCoupons wineCoupons = wineCouponsDao.find(wineCouponsId);
        if (null == wineCoupons) {
            logger.info("酒券方案不存在，酒券ID:" + wineCouponsId);
            return null;
        }
        WineCouponsModel model = WineCouponsModel.instance(wineCoupons);

        // 检测酒券常规属性
        boolean checkResult = model.checkUseModel();
        if (!checkResult) {
            return null;
        }
        // 如果发放方式不是固定金额则返回null
        if (model.WINE_COUPONS_PAY_FIXED_AMOUNT != model.getPayType()) {
            return null;
        }

        // 如果酒券金额大于0则发放酒券
        if (model.getAmount() > 0) {
            UserWineCoupons userWineCouponsn = new UserWineCoupons(user,
                    model.getName(), model.getAmount(), model.getType(),
                    model.getValidDay(), UserWineCouponsCategory.VERIFY_FULL_BORROW_SUCCESS,0,sourceType);

            // 更新酒券已发放数量
            wineCoupons.setIssueNum(wineCoupons.getIssueNum() + 1);
            wineCouponsDao.update(wineCoupons);

            return userWineCouponsDao.save(userWineCouponsn);
        }
        return null;
    }

    /**
     * 计算酒券发放金额
     *
     * @param money 用户操作金额
     * @param model 酒券方案
     * @return
     */
    @SuppressWarnings("static-access")
    public double calculationAmount(double money, WineCouponsModel model) {
        // 酒券发放金额
        double amount = 0;
        // 发放方式为固定金额
        if (model.WINE_COUPONS_PAY_FIXED_AMOUNT == model.getPayType()) {
            amount = model.getAmount();
            // 如果发放为固定金额则直接返回结果，不需要执行下面操作
            return amount;
        }
        // 酒券金额取整
        amount = BigDecimalUtil.round(amount, 0);
        return amount;
    }

    @Override
    public UserWineCoupons update(UserWineCoupons userWineCoupons) {
        return userWineCouponsDao.update(userWineCoupons);
    }

    @Override
    public void doInvalid(long id) {
        userWineCouponsDao.doInvalid(id);
    }

    @Override
    public List<UserWineCouponsModel> useableList(long userId) {
    	List<UserWineCoupons> list = userWineCouponsDao.useableList(userId);
    	if(list == null){
    		return Collections.emptyList();
    	}
    	List<UserWineCouponsModel> modelList = new ArrayList<UserWineCouponsModel>(list.size());
        for (UserWineCoupons userWineCoupons : list) {
            UserWineCouponsModel userWineCouponsModel = new UserWineCouponsModel();
            BeanCopierUtils.copyProperties(userWineCoupons, userWineCouponsModel);
            int remainDays = DateUtil.daysBetween(DateUtil.getNow(), userWineCoupons.getExpiredTime());
            userWineCouponsModel.setRemainDays(remainDays);
            modelList.add(userWineCouponsModel);
        }
        return modelList;
    }

    @Override
    public double getTotalAmountByIds(long[] ids, long toUserId) {
        return userWineCouponsDao.getTotalAmountByIds(ids, toUserId);
    }

    @Override
    public double getTenderUseAmount(long tenderId) {
        return userWineCouponsDao.getTenderUseAmount(tenderId);
    }

    @Override
    public void tenderBorrowFreezeWineCoupons(BorrowTender borrowTender, long[] wineCouponsIds) {
        userWineCouponsDao.tenderBorrowFreezeWineCoupons(borrowTender, wineCouponsIds);
    }

    @Override
    public void tenderBorrowUseWineCoupons(long tenderId) {
        userWineCouponsDao.tenderBorrowUseWineCoupons(tenderId);
    }

    @Override
    public void tenderBorrowFailUseWineCoupons(BorrowTender borrowTender) {
        userWineCouponsDao.tenderBorrowFailUseWineCoupons(borrowTender);
    }

    @Override
    public double getTotalAmountByUseTypeANdKeyId(String useType, long keyId) {
        return userWineCouponsDao.getTotalAmountByUseTypeANdKeyId(useType, keyId);
    }

    @Override
    public int userableCount(long userId) {
        return userWineCouponsDao.userableCount(userId);
    }

    @Override
    public boolean checkWineCoupons(long[] wineCouponsIds, User user) {
        return userWineCouponsDao.checkWineCoupons(wineCouponsIds, user);
    }

    @Override
    public double[] getUseWineCouponsSumByStatus(int status, String year) {
        double[] amounts = new double[12];
        String date;
        for (int i = 0; i < 12; i++) {
            date = year + (i > 8 ? "-" : "-0") + (i + 1);
            amounts[i] = userWineCouponsDao.getUseWineCouponsSumByStatus(status, date);
        }
        return amounts;
    }
    @Override
    public void wineCouponsExpireDispose() {
        userWineCouponsDao.wineCouponsExpireDispose();
    }
    
    @Override
    public void updateStatus(long id, byte status, byte preStatus) {
        String sql = "UPDATE UserWineCoupons SET status = :status ,useTime = NOW() WHERE id = :id AND status = :preStatus";
        Query query = em.createQuery(sql);
        query.setParameter("status", status);
        query.setParameter("id", id);
        query.setParameter("preStatus", preStatus);
        int result = query.executeUpdate();
        if (result != 1) {
            logger.error("酒券兑换，更改状态失败！Id:" + id + ",result:" + result + ",status:" + status + ",preStatus:" + preStatus);
            throw new BusinessException("酒券已过期或已被兑换！", 1);
        }
        refresh(super.find(id));
    }
}
